#include "judgesys21.h"


static void JudegMessageArrange(P_rxJudge_Mesg_t prx_mesg);
static void Inter_RobotMesgArrange(P_rxPackMesg_t packmesg);
static void Client_TX_Message(P_client_interactive_mesg_t pclient_mesg);
static uint16_t GetClientID(uint16_t robot_id);
static float Trans_Char2Float(uint8_t *pData);
static  void Trans_Float2Char(float input, uint8_t *array);
static  void Trans_Uint16ToChar(uint16_t input, uint8_t *array);
static uint8_t Verify_CRC8_Check_Sum(unsigned char *pchMessage, unsigned int dwLength);
static uint32_t Verify_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength);
static void Append_CRC8_Check_Sum(unsigned char *pchMessage, unsigned int dwLength);
static void Append_CRC16_Check_Sum(uint8_t * pchMessage, uint32_t dwLength);
static uint16_t GetReciverID(uint16_t robot_type);

uint8_t CurrentRobotId = R_RobotId_Infantry1; //默认初始ID为红色3号步兵
uint8_t interactTxData[INTERNATION_DART_PACK_SIZE];//交互数据发送缓存
JudgeRX_State_t	JudgeStateMachine;	//裁判系统状态机

/****************串口外设选择*********************/
#if HardwareType == Common_Hardware_Type
#define dma_send_handle hdma_u2tx
#define UARTxHandle	UART2Handle
#define USARTx USART2
#elif HardwareType == Engineer_Hardware_Type
#define dma_send_handle hdma_u3tx
#define UARTxHandle	UART3Handle
#define USARTx USART3
#endif
/************************************************/


//裁判系统初始化
void JudgeSys_Init(P_Judge_HANDLE_t pjud_hadl)
{
	#if HardwareType == Common_Hardware_Type
    UART2_Init(115200);
	#elif HardwareType == Engineer_Hardware_Type
	UART3_Init(115200);
	#endif
    JudgeStateMachine = JUD_FrameHeader_SOF;
}



//裁判系统状态机
void JudgeSys_RX_Message(uint8_t rxData, P_rxJudge_Mesg_t prx_mesg)
{
    static uint16_t i = 0;
    static uint8_t DataLenth_count = 0;
    static uint8_t CMDID_count = 0;
    static uint8_t CRC16_count = 0;
    switch(JudgeStateMachine)		//状态机接收数据
    {
        case (JUD_FrameHeader_SOF)://帧头部分
        {
            if(rxData == JUDGE_FRAME_HEADER_SOF)				//起始字节
            {
                prx_mesg->PackMesg.PackData[0] = rxData;
                JudgeStateMachine = JUD_FrameHeader_DataLength;	
                DataLenth_count = 0;
            }
            else
            {
                JudgeStateMachine = JUD_FrameHeader_SOF;
            }
            break;
        }
        case (JUD_FrameHeader_DataLength):
        {
            if(DataLenth_count == 0)
            {
                prx_mesg->PackMesg.PackData[1] = rxData;
                DataLenth_count = 1;
            }
            else if(DataLenth_count == 1)
            {
                prx_mesg->PackMesg.PackData[2] = rxData;		//数据长度
				prx_mesg->PackMesg.PACKDATA.dataLength = (prx_mesg->PackMesg.PackData[2]<<8)|prx_mesg->PackMesg.PackData[1];
                JudgeStateMachine = JUD_FrameHeader_Seq;
            }
            else
            {
                JudgeStateMachine = JUD_FrameHeader_SOF;
            }
            break;
        }
        case (JUD_FrameHeader_Seq):
        {
            prx_mesg->PackMesg.PackData[3] = rxData;
            prx_mesg->PackMesg.PACKDATA.packSeq = rxData;	
            JudgeStateMachine = JUD_FrameCRC8;
            break;
        }
        case (JUD_FrameCRC8):
        {
            prx_mesg->PackMesg.PackData[4] = rxData;
            prx_mesg->PackMesg.PACKDATA.crc8Check = rxData;
            if(Verify_CRC8_Check_Sum(prx_mesg->PackMesg.PackData, JUDGE_FRAME_HEADER_LENGTH))
            {
                CMDID_count = 0;
                JudgeStateMachine = JUD_CmdID;
            }
            else
            {
                JudgeStateMachine = JUD_FrameHeader_SOF;
            }
            break;
        }
        case (JUD_CmdID):
        {
            if(CMDID_count == 0)
            {
                CMDID_count = 1;
                prx_mesg->PackMesg.PackData[5] = rxData;
            }
            else if(CMDID_count == 1)
            {
                prx_mesg->PackMesg.PackData[6] = rxData;
                prx_mesg->PackMesg.PACKDATA.cmdId = (prx_mesg->PackMesg.PackData[6]<<8)|prx_mesg->PackMesg.PackData[5];
                i = 0;
                JudgeStateMachine = JUD_DATA;
            }
            else
            {
                JudgeStateMachine = JUD_FrameHeader_SOF;
            }
            break;
        }
        case (JUD_DATA):
        {
            if(i < prx_mesg->PackMesg.PACKDATA.dataLength)
            {
                prx_mesg->PackMesg.PackData[7 + i] = rxData;
				i++;
            }
            if(i >= prx_mesg->PackMesg.PACKDATA.dataLength)
            {
                CRC16_count = 0;
                JudgeStateMachine = JUD_FrameTail;
            }
            break;
        }
        case (JUD_FrameTail):
        {
            if(CRC16_count == 0)
            {
                CRC16_count = 1;
                prx_mesg->PackMesg.PackData[7 + prx_mesg->PackMesg.PACKDATA.dataLength] = rxData;
            }
            else if(CRC16_count == 1)
            {
                prx_mesg->PackMesg.PackData[8 + prx_mesg->PackMesg.PACKDATA.dataLength] = rxData;
                prx_mesg->PackMesg.PACKDATA.crc16Check = (rxData<<8)|prx_mesg->PackMesg.PackData[7 + prx_mesg->PackMesg.PACKDATA.dataLength];
                if(Verify_CRC16_Check_Sum(prx_mesg->PackMesg.PackData, 9 + prx_mesg->PackMesg.PACKDATA.dataLength))
                {
                    JudegMessageArrange(prx_mesg);
                }
                JudgeStateMachine = JUD_FrameHeader_SOF;
            }
            else
            {
                JudgeStateMachine = JUD_FrameHeader_SOF;
            }
        }
        default:;
    }
}
float Cap_Energy;	// 考虑变量换个位置，代表需要画什么样图形
//交互数据发送到裁判，其中包括与客户端和机器人通信信息
void JudgeSys_TX_Message(P_txJudge_Mesg_t ptx_mesg)
{
    static uint8_t DataCmdIdErrorCount = 0;
    if(ptx_mesg->tx_data_cmd_id == CLIENT_DATA_CMD_ID)
    {
      Client_TX_Message(&ptx_mesg->ClientMesg);
    }
    else if(ptx_mesg->tx_data_cmd_id == GRAPHIC_SINGLE_DATA_CMD_ID)
    {
		  UI_ShowEnergy(Cap_Energy);
    }
    else if(ptx_mesg->tx_data_cmd_id >= ROBOT_DATA_CMD_ID_MIN && ptx_mesg->tx_data_cmd_id <= ROBOT_DATA_CMD_ID_MAX)
    {
		//飞镖数据发送测试
      Robot_TX_Message(&ptx_mesg->RobotMesg,0x0200,R_RobotId_Dart);
    }
    else
    {
        DataCmdIdErrorCount++;
    }
}




//----------------------------------------LYX编写开始---------------------------------------------------------------------------

//写在前面：后面的代码因为不懂一些规范，且为了书写方便，把所有需要的全局变量直接放在函数的前面了，李哥移植的时候可以把变量的位置修改一下
//共有以下函数
//1.客户端剩余电容能量显示（显示的位置大概在左下角）
//2.客户端图层删除 删除一层图层或者所有图层
//3.客户端字符发送函数，这个需要初始化需要发送字符各个数据的变量
//4.客户端绘制两个图形，需要初始化变量
//5.一个比较齐全的函数，但是可能会有小bug
//注意，如果需要精度值较高，需要较快的调用函数频率


//--------------------------------------------应用层函数------------------------------------------------------------------------
/******************************************************
 * @data	2020.10.13 
 * @brie	客户端底盘电容剩余能量显示函数
 * @input	电容剩余能量
 * @output	无
 * @mader	柳煜翔   15773186732
 * @note	大致逻辑：先书写提示字符，然后先增加电容剩余能量，之后就是修改电容能量剩余值
 * ***************************************************/
//所需要的新变量
graphic_interactive_mesg_t Remain_Energy;
uint8_t IFDRAW = 1;
void UI_ShowEnergy(float UI_Cap_Remain_Energy)
{
	if(IFDRAW == 1)
	{
		Refresh_Graph(DLETE_ALL,0);
		IFDRAW++;
	}
	//先书写字符:Cap_Energy
	else if((IFDRAW<=5)&&(IFDRAW>=2))
	{
		Remain_Energy.graphic_data.graphic_name[0] = 0xff;
		Remain_Energy.graphic_data.graphic_name[1] = 0xff;
		Remain_Energy.graphic_data.graphic_name[2] = 0xff;
		Remain_Energy.graphic_data.operate_tpye = 1;              //增加图形
		Remain_Energy.graphic_data.graphic_tpye = 7;              //画字符
		Remain_Energy.graphic_data.layer        = 9;              //第9层图层
		Remain_Energy.graphic_data.color        = 8;              //白色
		Remain_Energy.graphic_data.start_angle  = 20;             //字体大小
		Remain_Energy.graphic_data.end_angle    = 13;             //字符长度
		Remain_Energy.graphic_data.width        = 3;              //线条宽度
		Remain_Energy.graphic_data.start_x      = 550;            
		Remain_Energy.graphic_data.start_y      = 150;
		strcpy(Remain_Energy.Char_TX_PACK,"Cap_Energy:");
		Char_TX_Message(&Remain_Energy);
		IFDRAW++;												  //发送信号4次，防止掉包
	}
	//然后是增加一个字符
	else if((IFDRAW>5) && (IFDRAW<=8))												
	{
		Remain_Energy.graphic_data.graphic_name[0] = 0x00;
		Remain_Energy.graphic_data.graphic_name[1] = 0x00;
		Remain_Energy.graphic_data.graphic_name[2] = 0x00;
		Remain_Energy.graphic_data.operate_tpye = 1;              //增加图形
		Remain_Energy.graphic_data.graphic_tpye = 5;              //画浮点
		Remain_Energy.graphic_data.layer        = 0;              //第0层图层
		Remain_Energy.graphic_data.color        = 0;              //红蓝主色
		Remain_Energy.graphic_data.start_angle  = 20;             //字体大小
		Remain_Energy.graphic_data.end_angle    = 13;             //字符长度
		Remain_Energy.graphic_data.width        = 3;              //线条宽度
		Remain_Energy.graphic_data.start_x      = 760;            
		Remain_Energy.graphic_data.start_y      = 150;
		Remain_Energy.UIFloat					= UI_Cap_Remain_Energy;
		Graphic_TX_Message(&Remain_Energy, FLOAT);
		IFDRAW++;												//发送信号3次，防止掉包
	}
	else if((IFDRAW>8)&&(IFDRAW <=12))												
	{
		Remain_Energy.graphic_data.graphic_name[0] = 0x00;
		Remain_Energy.graphic_data.graphic_name[1] = 0x00;
		Remain_Energy.graphic_data.graphic_name[2] = 0x00;
		Remain_Energy.graphic_data.operate_tpye = 2;              //修改图形
		Remain_Energy.graphic_data.graphic_tpye = 5;              //画浮点
		Remain_Energy.graphic_data.layer        = 0;              //第0层图层
		Remain_Energy.graphic_data.color        = 0;              //红蓝主色
		Remain_Energy.graphic_data.start_angle  = 20;             //字体大小
		Remain_Energy.graphic_data.end_angle    = 13;             //字符长度
		Remain_Energy.graphic_data.width        = 3;              //线条宽度
		Remain_Energy.graphic_data.start_x      = 760;            
		Remain_Energy.graphic_data.start_y      = 150;
		Remain_Energy.UIFloat				    = UI_Cap_Remain_Energy;
		Graphic_TX_Message(&Remain_Energy, FLOAT);
	}
}

/******************************************************
 * @data	2020.9.11 
 * @brie	客户端图形绘制，这个是比较齐全的画图函数，各个功能都实现了
 * @input	graphic_interactive_mesg_t  用户自定义数据结构体
 * @output	无
 * @mader	柳煜翔   15773186732
 * @note	 	可以根据TypeUI的不同的值来判断需要画什么图，如果只要画一个图形，这个函数是很好的选择 但是需要画的图形赋值过来的值必须是按照通信协议给P_Graphic_Mesg所指向的值赋值
 * TpyeUI是需要画的图象类型
 * ***************************************************/
/*所需要的新变量*/
/*函数主体*/
void Graphic_TX_Message(P_graphic_interactive_mesg_t P_Graphic_Mesg,uint8_t TpyeUI)
{
	/*全屏的圆心位置是960，540*/
	static uint8_t Graph_ClientPackSeq = 0;
	static uint8_t count;
	static uint8_t Graph_TX_Message[GRAPHIC_PACK_SIZE_SINGLE];	// 画一个图形，只需要30个字节
	static float UIFloat;
	static int UIInt;
	count++;																	//刷新UI标志位
	// 确定收发ID 
	P_Graphic_Mesg->header_data.data_cmd_ID		= GRAPHIC_SINGLE_DATA_CMD_ID;
	P_Graphic_Mesg->header_data.sender_ID		= CurrentRobotId;
    P_Graphic_Mesg->header_data.receiver_ID		= GetClientID(CurrentRobotId);		
	// 按照协议赋值
	Graph_TX_Message[0] = (uint8_t)JUDGE_FRAME_HEADER_SOF;				        //数据头 0xA5
	Trans_Uint16ToChar(GRAPHIC_DATA_LENGTH, &Graph_TX_Message[1]);              //数据的长度	这个地方的LENGTH为21
	Graph_TX_Message[3] = Graph_ClientPackSeq++;								//数据包的序号
	if(Graph_ClientPackSeq >= 255)Graph_ClientPackSeq = 0;				       	//溢出之后恢复数据
	Append_CRC8_Check_Sum(Graph_TX_Message, JUDGE_FRAME_HEADER_LENGTH);	        //增加CRC校验码
	Trans_Uint16ToChar(cmdID_ROBOT_INTER, &Graph_TX_Message[5]);				//cmd_ID 两字节	机器人间交互数据这里是0x0301
	if(TpyeUI == CHAR)															//刷新之后先判断是否是发送字符
	{
		Char_TX_Message(P_Graphic_Mesg);
		return;
	}
	//下面是数据包	
	Trans_Uint16ToChar(P_Graphic_Mesg->header_data.data_cmd_ID, &Graph_TX_Message[7]);	                //cmd_ID 0x0101
	Trans_Uint16ToChar(P_Graphic_Mesg->header_data.sender_ID, &Graph_TX_Message[9]);		            //发送者ID
	Trans_Uint16ToChar(P_Graphic_Mesg->header_data.receiver_ID, &Graph_TX_Message[11]);	                //接收者ID
	Graph_TX_Message[13] = P_Graphic_Mesg->graphic_data.graphic_name[0];								//把图形名字传过去
	Graph_TX_Message[14] = P_Graphic_Mesg->graphic_data.graphic_name[1];								//不同图形的名字画出来的图形不会重复，这样不会重叠
	Graph_TX_Message[15] = P_Graphic_Mesg->graphic_data.graphic_name[2];
	Graph_TX_Message[16] = ((P_Graphic_Mesg->graphic_data.graphic_tpye<<3) | P_Graphic_Mesg->graphic_data.operate_tpye)     & 0xff;//为1的时候是增加图层
	Graph_TX_Message[16] = ((P_Graphic_Mesg->graphic_data.layer<<6)	|	Graph_TX_Message[16])								& 0xff;
	Graph_TX_Message[17] = ((P_Graphic_Mesg->graphic_data.layer>>2) | (P_Graphic_Mesg->graphic_data.color<<2)) 				& 0xff;
	Graph_TX_Message[17] = ((Graph_TX_Message[17]) | (P_Graphic_Mesg->graphic_data.start_angle<<6))							& 0xff;
	Graph_TX_Message[18] = ((P_Graphic_Mesg->graphic_data.start_angle>>2) | (P_Graphic_Mesg->graphic_data.end_angle<<7))    & 0xff;
	Graph_TX_Message[19] = (P_Graphic_Mesg->graphic_data.end_angle>>1)														& 0xff;
	Graph_TX_Message[20] = P_Graphic_Mesg->graphic_data.width  																& 0xff;
	Graph_TX_Message[21] = ((P_Graphic_Mesg->graphic_data.width>>8) | (P_Graphic_Mesg->graphic_data.start_x<<2))    		& 0xff;
	Graph_TX_Message[22] = ((P_Graphic_Mesg->graphic_data.start_x>>6) | (P_Graphic_Mesg->graphic_data.start_y<<5))			& 0xff;
	Graph_TX_Message[23] = (P_Graphic_Mesg->graphic_data.start_y>>3)														& 0xff;
	
    if(TpyeUI == GRAPHIC)																				//画图指令
	{
		Graph_TX_Message[24] = P_Graphic_Mesg->graphic_data.radius  													    		& 0xff;
		Graph_TX_Message[25] = ((P_Graphic_Mesg->graphic_data.radius>>8) | (P_Graphic_Mesg->graphic_data.end_x<<2))    				& 0xff;
		Graph_TX_Message[26] = ((P_Graphic_Mesg->graphic_data.end_x	>>6) | (P_Graphic_Mesg->graphic_data.end_y<<5))					& 0xff;
		Graph_TX_Message[27] = (P_Graphic_Mesg->graphic_data.end_y>>3)																& 0xff;
	}
	else if(TpyeUI == FLOAT)																													 //浮点数UI指令
	{
		UIFloat = P_Graphic_Mesg -> UIFloat;
		Trans_Float2Char(UIFloat,&Graph_TX_Message[24]); 																																								
	}
	else if(TpyeUI == INT)																													 	 //整型UI指令
	{
		UIInt = P_Graphic_Mesg -> UIInt;
		Graph_TX_Message[24] = UIInt 									& 0xff;
		Graph_TX_Message[25] = UIInt>>8									& 0xff;
		Graph_TX_Message[26] = UIInt>>16								& 0xff;
		Graph_TX_Message[27] = UIInt>>24								& 0xff;
	}
	Append_CRC16_Check_Sum(Graph_TX_Message, GRAPHIC_PACK_SIZE_SINGLE);
	
	if(__HAL_DMA_GET_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6) == RESET)
    {
        UARTxHandle.hdmatx->Instance->NDTR = (uint16_t)GRAPHIC_PACK_SIZE_SINGLE;
		SET_BIT(UARTxHandle.Instance->CR3, USART_CR3_DMAT);
        dma_send_handle.Instance->PAR = (uint32_t)&USARTx->DR;
        dma_send_handle.Instance->M0AR = (uint32_t)Graph_TX_Message;
        __HAL_DMA_ENABLE(UARTxHandle.hdmatx);
    }
    else
    {
        __HAL_DMA_CLEAR_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6);
        __HAL_DMA_DISABLE(UARTxHandle.hdmatx);
    }
}

/******************************************************
 * @data	2020.10.5 
 * @brie	客户端字符发送函数
 * @input	字符初始化变量P_graphic_interactive_mesg_t，里面的信息包括字符的长度，大小，图形类型等等
 * @output	无
 * @mader	柳煜翔   15773186732
 * @note	数据包头的ID：0x0110  
* 如果需要修改字符的值，注意不要删除字符，查阅规则手册将增加图形命令改为修改图形命令即可
 * ***************************************************/
/*所需要的新变量*/
//char Char_TX_PACK[30];								//需要发送的字符
/*函数主体*/
void Char_TX_Message(P_graphic_interactive_mesg_t P_Graphic_Mesg)
{
	static uint8_t Graph_ClientPackSeq = 0;
	static uint8_t count;
	static uint8_t Char_Message[CHAR_PACK_SIZE];		            //字符发送数据包
	uint8_t i;
	count++;
	
	Char_Message[0] = (uint8_t)JUDGE_FRAME_HEADER_SOF;							//数据头 0xA5
	Trans_Uint16ToChar(CHAR_DATA_LENGTH, &Char_Message[1]);						//数据的长度	
	Char_Message[3] = Graph_ClientPackSeq++;									//数据包的序号
	if(Graph_ClientPackSeq >= 255)Graph_ClientPackSeq = 0;						//溢出之后恢复数据
	Append_CRC8_Check_Sum(Char_Message, JUDGE_FRAME_HEADER_LENGTH);				//增加CRC校验码
	Trans_Uint16ToChar(cmdID_ROBOT_INTER, &Char_Message[5]);					//cmd_ID 两字节	机器人间交互数据这里是0x0301
	
	//下面是数据包
	Trans_Uint16ToChar(GRAPHIC_SINGLE_DATA_CMD_ID, &Char_Message[7]);				//cmd_ID 0x0110
	Trans_Uint16ToChar(CurrentRobotId, &Char_Message[9]);						//发送者ID
	Trans_Uint16ToChar(GetClientID(CurrentRobotId), &Char_Message[11]);			//接收者ID
	Char_Message[13] = P_Graphic_Mesg->graphic_data.graphic_name[0];			//把图形名字传过去
	Char_Message[14] = P_Graphic_Mesg->graphic_data.graphic_name[1];			//一个图层里面，不同名字的图形不会重复画在一起
	Char_Message[15] = P_Graphic_Mesg->graphic_data.graphic_name[2];
	Char_Message[16] = ((P_Graphic_Mesg->graphic_data.graphic_tpye<<3) | P_Graphic_Mesg->graphic_data.operate_tpye) 								& 0xff;//为1的时候是增加图形
	Char_Message[16] = ((P_Graphic_Mesg->graphic_data.layer<<6) |	Char_Message[16])							            							& 0xff;
	Char_Message[17] = ((P_Graphic_Mesg->graphic_data.layer>>2) | (P_Graphic_Mesg->graphic_data.color <<2)) 											& 0xff;
	Char_Message[17] = ((Char_Message[17]) | (P_Graphic_Mesg->graphic_data.start_angle<<6))							    								& 0xff;
	Char_Message[18] = (((P_Graphic_Mesg->graphic_data.start_angle>>2) | P_Graphic_Mesg->graphic_data.end_angle<<7))									& 0xff;
	Char_Message[19] = (P_Graphic_Mesg->graphic_data.end_angle>>1)													    								& 0xff;
	Char_Message[20] = P_Graphic_Mesg->graphic_data.width  														        								& 0xff;
	Char_Message[21] = ((P_Graphic_Mesg->graphic_data.width>>8) | (P_Graphic_Mesg->graphic_data.start_x<<2))    										& 0xff;
	Char_Message[22] = ((P_Graphic_Mesg->graphic_data.start_x>>6) | (P_Graphic_Mesg->graphic_data.start_y<<5))											& 0xff;
	Char_Message[23] = (P_Graphic_Mesg->graphic_data.start_y>>3)													        							& 0xff;
	Char_Message[24] = 0x00																																& 0xff;
	Char_Message[25] = 0x00	    																														& 0xff;
	Char_Message[26] = 0x00																																& 0xff;
	Char_Message[27] = 0x00																																& 0xff;
	i = 0;
	while(i<30)
	{
		Char_Message[28+i] = P_Graphic_Mesg->Char_TX_PACK[i];
		i++;
	}
	Append_CRC16_Check_Sum(Char_Message, CHAR_PACK_SIZE);
	
	if(__HAL_DMA_GET_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6) == RESET)
	{
			UARTxHandle.hdmatx->Instance->NDTR = (uint16_t)CHAR_PACK_SIZE;
			SET_BIT(UARTxHandle.Instance->CR3, USART_CR3_DMAT);
			dma_send_handle.Instance->PAR = (uint32_t)&USARTx->DR;
			dma_send_handle.Instance->M0AR = (uint32_t)Char_Message;
			__HAL_DMA_ENABLE(UARTxHandle.hdmatx);
	}
	else
	{
			__HAL_DMA_CLEAR_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6);
			__HAL_DMA_DISABLE(UARTxHandle.hdmatx);
	}
}



/*------------------------------------------------底层驱动------------------------------------------------------------------------------*/
/******************************************************
 * @data	2020.10.5 
 * @brie	客户端图层删除
 * @input	图形操作方式 删除全部图层/一层，对应的图层
 * @output	无
 * @mader	柳煜翔   15773186732
 * @note	若是第一个变量要删除所有图层，第二个参数可以为任意值
 operate_graph_tpye变量有两个，DLETE_ALL和DLETE_ONE 如字体意思
 graphic_tpye 图层上限看一下规则 应该是8层 不太记得了
 * ***************************************************/
/*函数主体*/
void Refresh_Graph(uint8_t operate_graph_tpye,uint8_t graphic_tpye)	//
{
	static uint8_t Graph_ClientPackSeq = 0;
	static uint8_t Refresh_TX_Message[GRAPHIC_REFRESHPACK_SIZE];	//刷新图形数据包
	// 按照协议赋值
	Refresh_TX_Message[0] = (uint8_t)JUDGE_FRAME_HEADER_SOF;									//数据头 0xA5
	Trans_Uint16ToChar(REFRESHPACK_DATA_LENGTH, &Refresh_TX_Message[1]);						//数据的长度
	Refresh_TX_Message[3] = Graph_ClientPackSeq++;												//数据包的序号
	if(Graph_ClientPackSeq >= 255)Graph_ClientPackSeq = 0;										//溢出之后恢复数据
	Append_CRC8_Check_Sum(Refresh_TX_Message, JUDGE_FRAME_HEADER_LENGTH);						//增加CRC校验码
	Trans_Uint16ToChar(cmdID_ROBOT_INTER, &Refresh_TX_Message[5]);								//cmd_ID 两字节	
	
	//下面是数据包
	Trans_Uint16ToChar(GRAPHIC_SINGLE_DATA_CMD_ID, &Refresh_TX_Message[7]);						//cmd_ID 0x0100
	Trans_Uint16ToChar(CurrentRobotId, &Refresh_TX_Message[9]);									//发送者ID
	Trans_Uint16ToChar(GetClientID(CurrentRobotId), &Refresh_TX_Message[11]);		    		//接收者ID
	if(operate_graph_tpye == DLETE_ALL)
	{
		Refresh_TX_Message[13] = DLETE_ALL;
		Refresh_TX_Message[14] = 0x00;															//删除所有图形的时候，为空
	}
	else if(operate_graph_tpye == DLETE_ONE)
	{
		Refresh_TX_Message[13] = DLETE_ONE;
		Refresh_TX_Message[14] = graphic_tpye;													//删除第几层图层
	}	
	Append_CRC16_Check_Sum(Refresh_TX_Message, GRAPHIC_REFRESHPACK_SIZE);						//增加CRC16校验码
	//发送数据
	if(__HAL_DMA_GET_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6) == RESET)	
	{
			UARTxHandle.hdmatx->Instance->NDTR = (uint16_t)GRAPHIC_REFRESHPACK_SIZE;
			SET_BIT(UARTxHandle.Instance->CR3, USART_CR3_DMAT);
			dma_send_handle.Instance->PAR = (uint32_t)&USARTx->DR;
			dma_send_handle.Instance->M0AR = (uint32_t)Refresh_TX_Message;
			__HAL_DMA_ENABLE(UARTxHandle.hdmatx);
	}
	else
	{
			__HAL_DMA_CLEAR_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6);
			__HAL_DMA_DISABLE(UARTxHandle.hdmatx);
	}
}
/******************************************************
 * @data	2021.1.19 
 * @brie	客户端绘制1个图形
 * @input	graphic_interactive_mesg_t  用户自定义数据结构体
 * @output	无
 * @mader	柳煜翔   15773186732
 * @note	  
 * ***************************************************/
void UI_grapgic_One(ext_client_custom_graphic_single_t Tx_graphic_single)
{
	static uint8_t Graph_ClientPackSeq = 0;
	static uint8_t count;
	static uint8_t Graph_TX_Message[GRAPHIC_PACK_SIZE_SINGLE];	// 画一个图形，只需要30个字节
	count++;																	//刷新UI标志位		
	// 按照协议赋值
	Graph_TX_Message[0] = (uint8_t)JUDGE_FRAME_HEADER_SOF;				        //数据头 0xA5
	Trans_Uint16ToChar(GRAPHIC_DATA_LENGTH, &Graph_TX_Message[1]);              //数据的长度	这个地方的LENGTH为21
	Graph_TX_Message[3] = Graph_ClientPackSeq++;								//数据包的序号
	if(Graph_ClientPackSeq >= 255)Graph_ClientPackSeq = 0;				       	//溢出之后恢复数据
	Append_CRC8_Check_Sum(Graph_TX_Message, JUDGE_FRAME_HEADER_LENGTH);	        //增加CRC校验码
	Trans_Uint16ToChar(cmdID_ROBOT_INTER, &Graph_TX_Message[5]);				//cmd_ID 两字节	机器人间交互数据这里是0x0301
	//下面是数据包	
	Trans_Uint16ToChar(GRAPHIC_SINGLE_DATA_CMD_ID, &Graph_TX_Message[7]);	    //cmd_ID 0x0101
	Trans_Uint16ToChar(CurrentRobotId, &Graph_TX_Message[9]);		            //发送者ID
	Trans_Uint16ToChar(GetClientID(CurrentRobotId), &Graph_TX_Message[11]);	    //接收者ID
	Graph_TX_Message[13] = Tx_graphic_single.grapic_data_struct.graphic_name[0];						//把图形名字传过去
	Graph_TX_Message[14] = Tx_graphic_single.grapic_data_struct.graphic_name[1];						//不同图形的名字画出来的图形不会重复，这样不会重叠
	Graph_TX_Message[15] = Tx_graphic_single.grapic_data_struct.graphic_name[2];
	Graph_TX_Message[16] = ((Tx_graphic_single.grapic_data_struct.graphic_tpye<<3) | Tx_graphic_single.grapic_data_struct.operate_tpye)     & 0xff;//为1的时候是增加图层
	Graph_TX_Message[16] = ((Tx_graphic_single.grapic_data_struct.layer<<6)	| Graph_TX_Message[16])											& 0xff;
	Graph_TX_Message[17] = ((Tx_graphic_single.grapic_data_struct.layer>>2) | (Tx_graphic_single.grapic_data_struct.color<<2)) 				& 0xff;
	Graph_TX_Message[17] = ((Graph_TX_Message[17]) | (Tx_graphic_single.grapic_data_struct.start_angle<<6))									& 0xff;
	Graph_TX_Message[18] = ((Tx_graphic_single.grapic_data_struct.start_angle>>2) | (Tx_graphic_single.grapic_data_struct.end_angle<<7))    & 0xff;
	Graph_TX_Message[19] = (Tx_graphic_single.grapic_data_struct.end_angle>>1)																& 0xff;
	Graph_TX_Message[20] = Tx_graphic_single.grapic_data_struct.width  																		& 0xff;
	Graph_TX_Message[21] = ((Tx_graphic_single.grapic_data_struct.width>>8) | (Tx_graphic_single.grapic_data_struct.start_x<<2))    		& 0xff;
	Graph_TX_Message[22] = ((Tx_graphic_single.grapic_data_struct.start_x>>6) | (Tx_graphic_single.grapic_data_struct.start_y<<5))			& 0xff;
	Graph_TX_Message[23] = (Tx_graphic_single.grapic_data_struct.start_y>>3)																& 0xff;
	Graph_TX_Message[24] = Tx_graphic_single.grapic_data_struct.radius  													    			& 0xff;
	Graph_TX_Message[25] = ((Tx_graphic_single.grapic_data_struct.radius>>8) | (Tx_graphic_single.grapic_data_struct.end_x<<2))    			& 0xff;
	Graph_TX_Message[26] = ((Tx_graphic_single.grapic_data_struct.end_x	>>6) | (Tx_graphic_single.grapic_data_struct.end_y<<5))				& 0xff;
	Graph_TX_Message[27] = (Tx_graphic_single.grapic_data_struct.end_y>>3)																	& 0xff;
	Append_CRC16_Check_Sum(Graph_TX_Message, GRAPHIC_PACK_SIZE_SINGLE);
	if(__HAL_DMA_GET_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6) == RESET)
    {
        UARTxHandle.hdmatx->Instance->NDTR = (uint16_t)GRAPHIC_PACK_SIZE_SINGLE;
		SET_BIT(UARTxHandle.Instance->CR3, USART_CR3_DMAT);
        dma_send_handle.Instance->PAR = (uint32_t)&USARTx->DR;
        dma_send_handle.Instance->M0AR = (uint32_t)Graph_TX_Message;
        __HAL_DMA_ENABLE(UARTxHandle.hdmatx);
    }
    else
    {
        __HAL_DMA_CLEAR_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6);
        __HAL_DMA_DISABLE(UARTxHandle.hdmatx);
    }
}

/******************************************************
 * @data	2020.10.12 
 * @brie	客户端绘制2个图形
 * @input	graphic_interactive_mesg_t  用户自定义数据结构体
 * @output	无
 * @mader	柳煜翔   15773186732
 * @note	  
 * ***************************************************/
void UI_grapgic_double(ext_client_custom_graphic_double_t Tx_graphic_double)  
 {
    static uint8_t Graph_ClientPackSeq = 0;
    static uint8_t count;
	static uint8_t Graphic_TX_Message_Double[GRAPHIC_PACK_SIZE_DOUBLE];
    count++;
	Graphic_TX_Message_Double[0] = (uint8_t)JUDGE_FRAME_HEADER_SOF;								                             	//数据头 0xA5
	Trans_Uint16ToChar(GRAPHIC_DATA_LENGTH_DOUBLE, &Graphic_TX_Message_Double[1]);				                              	//数据的长度	
	Graphic_TX_Message_Double[3] = Graph_ClientPackSeq++;										                        		//数据包的序号
	if(Graph_ClientPackSeq >= 255)Graph_ClientPackSeq = 0;								                                        //溢出之后恢复数据
	Append_CRC8_Check_Sum(Graphic_TX_Message_Double, JUDGE_FRAME_HEADER_LENGTH);				                                //增加CRC校验码
	Trans_Uint16ToChar(cmdID_ROBOT_INTER, &Graphic_TX_Message_Double[5]);						                              	//cmd_ID 两字节	机器人间交互数据这里是0x0301
    //下面是数据包
	Trans_Uint16ToChar(GRAPHIC_DOUBLE_DATA_CMD_ID, &Graphic_TX_Message_Double[7]);					               	           //cmd_ID 0x0101
	Trans_Uint16ToChar(CurrentRobotId, &Graphic_TX_Message_Double[9]);							                                //发送者ID
	Trans_Uint16ToChar(GetClientID(CurrentRobotId), &Graphic_TX_Message_Double[11]);			                 	            //接收者ID
    //第一个图形	
	Graphic_TX_Message_Double[13] = Tx_graphic_double.grapic_data_struct[0].graphic_name[0];														//把图形名字传过去
	Graphic_TX_Message_Double[14] = Tx_graphic_double.grapic_data_struct[0].graphic_name[1];														//不同图形的名字画出来的图形不会重复，这样不会重叠
	Graphic_TX_Message_Double[15] = Tx_graphic_double.grapic_data_struct[0].graphic_name[2];
	Graphic_TX_Message_Double[16] = ((Tx_graphic_double.grapic_data_struct[0].graphic_tpye<<3) |Tx_graphic_double.grapic_data_struct[0].operate_tpye)   	& 0xff;//为1的时候是增加图层
	Graphic_TX_Message_Double[16] = ((Tx_graphic_double.grapic_data_struct[0].layer<<6)	|	Graphic_TX_Message_Double[16])					         		& 0xff;
	Graphic_TX_Message_Double[17] = ((Tx_graphic_double.grapic_data_struct[0].layer>>2) | (Tx_graphic_double.grapic_data_struct[0].color <<2)) 				& 0xff;
	Graphic_TX_Message_Double[17] = ((Graphic_TX_Message_Double[17]) | (Tx_graphic_double.grapic_data_struct[0].start_angle<<6))				 			& 0xff;
	Graphic_TX_Message_Double[18] = ((Tx_graphic_double.grapic_data_struct[0].start_angle>>2) | (Tx_graphic_double.grapic_data_struct[0].end_angle<<7)) 	& 0xff;
	Graphic_TX_Message_Double[19] = (Tx_graphic_double.grapic_data_struct[0].end_angle>>1)																	& 0xff;
	Graphic_TX_Message_Double[20] = Tx_graphic_double.grapic_data_struct[0].width  														            		& 0xff;
	Graphic_TX_Message_Double[21] = ((Tx_graphic_double.grapic_data_struct[0].width>>8) | (Tx_graphic_double.grapic_data_struct[0].start_x<<2))    			& 0xff;
	Graphic_TX_Message_Double[22] = ((Tx_graphic_double.grapic_data_struct[0].start_x>>6) | (Tx_graphic_double.grapic_data_struct[0].start_y<<5))			& 0xff;
	Graphic_TX_Message_Double[23] = (Tx_graphic_double.grapic_data_struct[0].start_y>>3)	                                                            	& 0xff;
	Graphic_TX_Message_Double[24] = Tx_graphic_double.grapic_data_struct[0].radius 										    								& 0xff; 									
	Graphic_TX_Message_Double[25] = ((Tx_graphic_double.grapic_data_struct[0].radius>>8) | (Tx_graphic_double.grapic_data_struct[0].end_x<<2))    			& 0xff;
	Graphic_TX_Message_Double[26] = ((Tx_graphic_double.grapic_data_struct[0].end_x	>>6) | (Tx_graphic_double.grapic_data_struct[0].end_y<<5))				& 0xff;
	Graphic_TX_Message_Double[27] = (Tx_graphic_double.grapic_data_struct[0].end_y>>3)	                                                                	& 0xff;
	//第二个图形
	Graphic_TX_Message_Double[28] = Tx_graphic_double.grapic_data_struct[1].graphic_name[0];													//把图形名字传过去
	Graphic_TX_Message_Double[29] = Tx_graphic_double.grapic_data_struct[1].graphic_name[1];													//不同图形的名字画出来的图形不会重复，这样不会重叠
	Graphic_TX_Message_Double[30] = Tx_graphic_double.grapic_data_struct[1].graphic_name[2];
	Graphic_TX_Message_Double[31] = ((Tx_graphic_double.grapic_data_struct[1].graphic_tpye<<3)|Tx_graphic_double.grapic_data_struct[1].operate_tpye)   		& 0xff;     //为1的时候是增加图层
	Graphic_TX_Message_Double[31] = ((Tx_graphic_double.grapic_data_struct[1].layer<<6)	|	Graphic_TX_Message_Double[16])					       			& 0xff;
	Graphic_TX_Message_Double[32] = ((Tx_graphic_double.grapic_data_struct[1].layer>>2) | (Tx_graphic_double.grapic_data_struct[1].color <<2)) 				& 0xff;
	Graphic_TX_Message_Double[32] = ((Graphic_TX_Message_Double[17]) | (Tx_graphic_double.grapic_data_struct[1].start_angle<<6))				        	& 0xff;
	Graphic_TX_Message_Double[33] = ((Tx_graphic_double.grapic_data_struct[1].start_angle>>2) | (Tx_graphic_double.grapic_data_struct[1].end_angle<<7)) 	& 0xff;
	Graphic_TX_Message_Double[34] = (Tx_graphic_double.grapic_data_struct[1].end_angle>>1)														        	& 0xff;
	Graphic_TX_Message_Double[35] = Tx_graphic_double.grapic_data_struct[1].width  														            		& 0xff;
	Graphic_TX_Message_Double[36] = ((Tx_graphic_double.grapic_data_struct[1].width>>8) | (Tx_graphic_double.grapic_data_struct[1].start_x<<2))    			& 0xff;
	Graphic_TX_Message_Double[37] = ((Tx_graphic_double.grapic_data_struct[1].start_x>>6) | (Tx_graphic_double.grapic_data_struct[1].start_y<<5))			& 0xff;
	Graphic_TX_Message_Double[38] = (Tx_graphic_double.grapic_data_struct[1].start_y>>3)	                                                            	& 0xff;
	Graphic_TX_Message_Double[39] = Tx_graphic_double.grapic_data_struct[1].radius 														               		& 0xff; 									
	Graphic_TX_Message_Double[40] = ((Tx_graphic_double.grapic_data_struct[1].radius>>8) | (Tx_graphic_double.grapic_data_struct[1].end_x<<2))    			& 0xff;
	Graphic_TX_Message_Double[41] = ((Tx_graphic_double.grapic_data_struct[1].end_x	>>6) | (Tx_graphic_double.grapic_data_struct[1].end_y<<5))				& 0xff;
	Graphic_TX_Message_Double[42] = (Tx_graphic_double.grapic_data_struct[1].end_y>>3)	                                                                	& 0xff;

  Append_CRC16_Check_Sum(Graphic_TX_Message_Double, GRAPHIC_PACK_SIZE_DOUBLE);
	
	if(__HAL_DMA_GET_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6) == RESET)
	{
			UARTxHandle.hdmatx->Instance->NDTR = (uint16_t)GRAPHIC_PACK_SIZE_DOUBLE;
			SET_BIT(UARTxHandle.Instance->CR3, USART_CR3_DMAT);
			dma_send_handle.Instance->PAR = (uint32_t)&USARTx->DR;
			dma_send_handle.Instance->M0AR = (uint32_t)Graphic_TX_Message_Double;
			__HAL_DMA_ENABLE(UARTxHandle.hdmatx);
	}
	else
	{
			__HAL_DMA_CLEAR_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6);
			__HAL_DMA_DISABLE(UARTxHandle.hdmatx);
    }
}

/******************************************************
 * @data	2020.10.12 
 * @brie	客户端绘制5个图形
 * @input	graphic_interactive_mesg_t  用户自定义数据结构体
 * @output	无
 * @mader	柳煜翔   15773186732
 * @note	  
 * ***************************************************/
void UI_grapgic_five(ext_client_custom_graphic_double_t Tx_graphic_double)  
 {
	 //因为目前没必要，暂时没写上
}

//------------------------------------------LYX编写结束----------------------------------------------

//裁判系统信息整理
static void JudegMessageArrange(P_rxJudge_Mesg_t prx_mesg)
{
    switch(prx_mesg->PackMesg.PACKDATA.cmdId)
    {
        case (cmdID_GAME_STATE):
        {
            prx_mesg->game_state.gamestate.value    = prx_mesg->PackMesg.PackData[7];
            prx_mesg->game_state.stage_remain_time  = (prx_mesg->PackMesg.PackData[9]<<8)|prx_mesg->PackMesg.PackData[8];
            break;
        }
        case (cmdID_GAME_RESULT):
        {
            prx_mesg->game_result.winner            = prx_mesg->PackMesg.PackData[7];
            break;
        }
        case (cmdID_ROBOT_HP_DATA):
        {
            prx_mesg->game_robot_HP.red_1_robot_HP  = (prx_mesg->PackMesg.PackData[8]<<8)|prx_mesg->PackMesg.PackData[7];
            prx_mesg->game_robot_HP.red_2_robot_HP  = (prx_mesg->PackMesg.PackData[10]<<8)|prx_mesg->PackMesg.PackData[9];
            prx_mesg->game_robot_HP.red_3_robot_HP  = (prx_mesg->PackMesg.PackData[12]<<8)|prx_mesg->PackMesg.PackData[11];
            prx_mesg->game_robot_HP.red_4_robot_HP  = (prx_mesg->PackMesg.PackData[14]<<8)|prx_mesg->PackMesg.PackData[13];
            prx_mesg->game_robot_HP.red_5_robot_HP  = (prx_mesg->PackMesg.PackData[16]<<8)|prx_mesg->PackMesg.PackData[15];
            prx_mesg->game_robot_HP.red_7_robot_HP  = (prx_mesg->PackMesg.PackData[18]<<8)|prx_mesg->PackMesg.PackData[17];
            prx_mesg->game_robot_HP.red_outpost_HP  = (prx_mesg->PackMesg.PackData[20]<<8)|prx_mesg->PackMesg.PackData[19];
            prx_mesg->game_robot_HP.red_base_HP     = (prx_mesg->PackMesg.PackData[22]<<8)|prx_mesg->PackMesg.PackData[21];

            prx_mesg->game_robot_HP.blue_1_robot_HP = (prx_mesg->PackMesg.PackData[24]<<8)|prx_mesg->PackMesg.PackData[23];
            prx_mesg->game_robot_HP.blue_2_robot_HP = (prx_mesg->PackMesg.PackData[26]<<8)|prx_mesg->PackMesg.PackData[25];
            prx_mesg->game_robot_HP.blue_3_robot_HP = (prx_mesg->PackMesg.PackData[28]<<8)|prx_mesg->PackMesg.PackData[27];
            prx_mesg->game_robot_HP.blue_4_robot_HP = (prx_mesg->PackMesg.PackData[30]<<8)|prx_mesg->PackMesg.PackData[29];
            prx_mesg->game_robot_HP.blue_5_robot_HP = (prx_mesg->PackMesg.PackData[32]<<8)|prx_mesg->PackMesg.PackData[31];
            prx_mesg->game_robot_HP.blue_7_robot_HP = (prx_mesg->PackMesg.PackData[34]<<8)|prx_mesg->PackMesg.PackData[33];
            prx_mesg->game_robot_HP.blue_outpost_HP = (prx_mesg->PackMesg.PackData[36]<<8)|prx_mesg->PackMesg.PackData[35];
            prx_mesg->game_robot_HP.blue_base_HP    = (prx_mesg->PackMesg.PackData[38]<<8)|prx_mesg->PackMesg.PackData[37];
            break;
        }
        case (cmdID_DART_STATUS):
        {
            prx_mesg->dart_state.dart_belong            =  prx_mesg->PackMesg.PackData[7];
            prx_mesg->dart_state.stage_remaining_time   = (prx_mesg->PackMesg.PackData[9]<<8)|prx_mesg->PackMesg.PackData[8];
            break;
        }
        case (cmdID_EVENT_DATA):
        {
            prx_mesg->event_data.event_type =   (prx_mesg->PackMesg.PackData[10]<<24)|(prx_mesg->PackMesg.PackData[9]<<16)| \
                                                (prx_mesg->PackMesg.PackData[8]<<8)|prx_mesg->PackMesg.PackData[7];
            break;
        }
        case (cmdID_SUPPLY_ACTION):
        {
            prx_mesg->supply_projectile_action.supply_projectile_id     = prx_mesg->PackMesg.PackData[7];
            prx_mesg->supply_projectile_action.supply_robot_id          = prx_mesg->PackMesg.PackData[8];
            prx_mesg->supply_projectile_action.supply_projectile_step   = prx_mesg->PackMesg.PackData[9];
            prx_mesg->supply_projectile_action.supply_projectile_num    = prx_mesg->PackMesg.PackData[10];
            break;
        }
        // case (cmdID_SUPPLY_BOOKING):
        // {
        //    prx_mesg->supply_projectile_booking.supply_projectile_id    = prx_mesg->PackMesg.PackData[7];
        //    prx_mesg->supply_projectile_booking.supply_robot_id         = prx_mesg->PackMesg.PackData[8];
        //    prx_mesg->supply_projectile_booking.supply_num              = prx_mesg->PackMesg.PackData[9];
        //     break;
        // }
        case (cmdID_REFEREE_WARNING):
        {
            prx_mesg->referee_warning.level         = prx_mesg->PackMesg.PackData[7];
            prx_mesg->referee_warning.foul_robot_id = prx_mesg->PackMesg.PackData[8];
            break;
        }
        case (cmdID_DART_REMAINING_TIME):
        {
            prx_mesg->dart_remaining_time.dart_remaining_time = prx_mesg->PackMesg.PackData[7];
            break;
        }
        case (cmdID_ROBOT_STATE):
        {
            prx_mesg->game_robot_state.robot_id                     = prx_mesg->PackMesg.PackData[7];
            prx_mesg->game_robot_state.robot_level                  = prx_mesg->PackMesg.PackData[8];
            prx_mesg->game_robot_state.remain_HP                    = (prx_mesg->PackMesg.PackData[10]<<8)|prx_mesg->PackMesg.PackData[9];
            prx_mesg->game_robot_state.max_HP                       = (prx_mesg->PackMesg.PackData[12]<<8)|prx_mesg->PackMesg.PackData[11];
            prx_mesg->game_robot_state.shooter_heat0_cooling_rate   = (prx_mesg->PackMesg.PackData[14]<<8)|prx_mesg->PackMesg.PackData[13];
            prx_mesg->game_robot_state.shooter_heat0_cooling_limit  = (prx_mesg->PackMesg.PackData[16]<<8)|prx_mesg->PackMesg.PackData[15];
            prx_mesg->game_robot_state.shooter_heat1_cooling_rate   = (prx_mesg->PackMesg.PackData[18]<<8)|prx_mesg->PackMesg.PackData[17];
            prx_mesg->game_robot_state.shooter_heat1_cooling_limit  = (prx_mesg->PackMesg.PackData[20]<<8)|prx_mesg->PackMesg.PackData[19];
            prx_mesg->game_robot_state.shooter_heat0_speed_limit    = prx_mesg->PackMesg.PackData[21];
            prx_mesg->game_robot_state.shooter_heat1_speed_limit    = prx_mesg->PackMesg.PackData[22];
            prx_mesg->game_robot_state.max_chassis_power            = prx_mesg->PackMesg.PackData[23];
            prx_mesg->game_robot_state.mainctrlpower.value          = prx_mesg->PackMesg.PackData[24];
            CurrentRobotId  = prx_mesg->game_robot_state.robot_id;
            break;
        }
        case (cmdID_POWER_HEAT):
        {
            prx_mesg->power_heat_data.chassis_volt              = (prx_mesg->PackMesg.PackData[8]<<8)|prx_mesg->PackMesg.PackData[7];
            prx_mesg->power_heat_data.chassis_current           = (prx_mesg->PackMesg.PackData[10]<<8)|prx_mesg->PackMesg.PackData[9];
            prx_mesg->power_heat_data.chassis_power             = Trans_Char2Float(&prx_mesg->PackMesg.PackData[11]);
            prx_mesg->power_heat_data.chassis_power_buffer      = (prx_mesg->PackMesg.PackData[16]<<8)|prx_mesg->PackMesg.PackData[15];
            prx_mesg->power_heat_data.shooter_heat0             = (prx_mesg->PackMesg.PackData[18]<<8)|prx_mesg->PackMesg.PackData[17];
            prx_mesg->power_heat_data.shooter_heat1             = (prx_mesg->PackMesg.PackData[20]<<8)|prx_mesg->PackMesg.PackData[19];
            prx_mesg->power_heat_data.mobile_shooter_heat2      = (prx_mesg->PackMesg.PackData[22]<<8)|prx_mesg->PackMesg.PackData[21];
            break;
        }
        case (cmdID_ROBOT_POS):
        {
            prx_mesg->game_robot_pos.x                          = Trans_Char2Float(&prx_mesg->PackMesg.PackData[7]);
            prx_mesg->game_robot_pos.y                          = Trans_Char2Float(&prx_mesg->PackMesg.PackData[11]);
            prx_mesg->game_robot_pos.z                          = Trans_Char2Float(&prx_mesg->PackMesg.PackData[15]);
            prx_mesg->game_robot_pos.yaw                        = Trans_Char2Float(&prx_mesg->PackMesg.PackData[19]);
            break;
        }
        case (cmdID_ROBOT_BUFF):
        {
            prx_mesg->buff_musk.power_rune_buff         = prx_mesg->PackMesg.PackData[7];
            break;
        }
        case (cmdID_AERIAL_ENERGY):
        {
            prx_mesg->aerial_robot_energy.energy_point  = (prx_mesg->PackMesg.PackData[8]<<8)|prx_mesg->PackMesg.PackData[7];
            prx_mesg->aerial_robot_energy.attack_time   = prx_mesg->PackMesg.PackData[9];
            break;
        }
        case (cmdID_HURT_STATE):
        {
            prx_mesg->robot_hurt.hurtstate.value        = prx_mesg->PackMesg.PackData[7];
            break;
        }
        case (cmdID_SHOOT_DATA):
        {
            prx_mesg->shoot_data.bullet_type            = prx_mesg->PackMesg.PackData[7];
            prx_mesg->shoot_data.bullet_freq            = prx_mesg->PackMesg.PackData[8];
            prx_mesg->shoot_data.bullet_speed           = Trans_Char2Float(&prx_mesg->PackMesg.PackData[9]);
            prx_mesg->shoot_data.current_bullet_num++;
            break;
        }
        case (cmdID_BULLET_REMAINING):
        {
            prx_mesg->bullet_remaining.bullet_remaining_num = (prx_mesg->PackMesg.PackData[8]<<8)|prx_mesg->PackMesg.PackData[7];
            break;
        }
        case (cmdID_RFID_STATUS):
        {
            prx_mesg->rfid_state.rfid_status = (prx_mesg->PackMesg.PackData[10]<<24)|(prx_mesg->PackMesg.PackData[9]<<16)| \
                                                (prx_mesg->PackMesg.PackData[8]<<8)|prx_mesg->PackMesg.PackData[7];
            break;
        }
        case (cmdID_DART_CLIENT_CMD):
        {
            prx_mesg->dart_client_cmd.dart_launch_opening_status    = prx_mesg->PackMesg.PackData[7];
            prx_mesg->dart_client_cmd.dart_attack_target            = prx_mesg->PackMesg.PackData[8];
            prx_mesg->dart_client_cmd.target_change_time            = (prx_mesg->PackMesg.PackData[10]<<8)|prx_mesg->PackMesg.PackData[9];
            prx_mesg->dart_client_cmd.first_dart_speed              = prx_mesg->PackMesg.PackData[11];
            prx_mesg->dart_client_cmd.second_dart_speed             = prx_mesg->PackMesg.PackData[12];
            prx_mesg->dart_client_cmd.third_dart_speed              = prx_mesg->PackMesg.PackData[13];
            prx_mesg->dart_client_cmd.fourth_dart_speed             = prx_mesg->PackMesg.PackData[14];
            prx_mesg->dart_client_cmd.last_dart_launch_time         = (prx_mesg->PackMesg.PackData[16]<<8)|prx_mesg->PackMesg.PackData[15];
            prx_mesg->dart_client_cmd.operate_launch_cmd_time       = (prx_mesg->PackMesg.PackData[18]<<8)|prx_mesg->PackMesg.PackData[17];
            break;
        }
        case (cmdID_ROBOT_INTER):
        {
//			LED_Off(LED_B);
//			LED_Off(LED_G);
//			LED_Off(LED_Y);
            Inter_RobotMesgArrange(&prx_mesg->PackMesg);
            break;
        }
		default:
		{
			//errorNumCount++;
		}
    }
}

float revdata;
uint16_t receiver_id;
uint16_t cmd_id;
uint16_t sender_id;
void Inter_RobotMesgArrange(P_rxPackMesg_t packmesg)
{

	cmd_id		= (packmesg->PackData[8]<<8)|packmesg->PackData[7];
	sender_id 	= (packmesg->PackData[10]<<8)|packmesg->PackData[9];
	receiver_id = (packmesg->PackData[12]<<8)|packmesg->PackData[11];
	switch(cmd_id)
	{
		case 0x0200:
			if(CurrentRobotId == receiver_id)
				revdata = Trans_Char2Float(&packmesg->PackData[13]);
				break;
	}	
}


uint8_t clientTxData[CLIENT_DATA_PACK_SIZE];
//将客户端自定义的数据发送到客户端显示
static void Client_TX_Message(P_client_interactive_mesg_t pclient_mesg)
{
    static uint8_t ClientPackSeq = 0;
    pclient_mesg->header_data.data_cmd_ID       = CLIENT_DATA_CMD_ID;
    pclient_mesg->header_data.sender_ID         = CurrentRobotId;
    pclient_mesg->header_data.receiver_ID       = GetClientID(CurrentRobotId);
    //按照协议赋值
    clientTxData[0]  = (uint8_t)JUDGE_FRAME_HEADER_SOF;
    Trans_Uint16ToChar(CLIENT_DATA_LENGTH, &clientTxData[1]);
    clientTxData[3]  = ClientPackSeq++;
    if(ClientPackSeq >= 255)ClientPackSeq = 0;
    Append_CRC8_Check_Sum(clientTxData, JUDGE_FRAME_HEADER_LENGTH);
    Trans_Uint16ToChar(cmdID_ROBOT_INTER, &clientTxData[5]);
    Trans_Uint16ToChar(pclient_mesg->header_data.data_cmd_ID, &clientTxData[7]);
    Trans_Uint16ToChar(pclient_mesg->header_data.sender_ID, &clientTxData[9]);
    Trans_Uint16ToChar(pclient_mesg->header_data.receiver_ID, &clientTxData[11]);
	Trans_Float2Char(pclient_mesg->custom_data.data1, &clientTxData[13]);
    Trans_Float2Char(pclient_mesg->custom_data.data2, &clientTxData[17]);
    Trans_Float2Char(pclient_mesg->custom_data.data3, &clientTxData[21]);
	clientTxData[25] = pclient_mesg->custom_data.masks.value;
    Append_CRC16_Check_Sum(clientTxData, CLIENT_DATA_PACK_SIZE);

    if(__HAL_DMA_GET_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6) == RESET)
    {
        UARTxHandle.hdmatx->Instance->NDTR = (uint16_t)CLIENT_DATA_PACK_SIZE;
        __HAL_DMA_ENABLE(UARTxHandle.hdmatx);
    }
    else
    {
        __HAL_DMA_CLEAR_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6);
        __HAL_DMA_DISABLE(UARTxHandle.hdmatx);
    }
    
    HAL_UART_Transmit_DMA(&UARTxHandle, clientTxData, CLIENT_DATA_PACK_SIZE);
    HAL_UART_Transmit(&UARTxHandle, clientTxData, CLIENT_DATA_PACK_SIZE, 5000);
	//可能需要用串口DMA发送
}


//将学生间自定义的数据发送到指定机器人裁判系统
void Robot_TX_Message(P_robot_interactive_mesg_t probotmesg,uint16_t Self_def_cmd,uint16_t Receiver_Type)
{
	static uint8_t InteractPackSeq = 0;
    probotmesg->header_data.data_cmd_ID       = Self_def_cmd;//0x0200-0x02FF数据段内容自定义
    probotmesg->header_data.sender_ID         = CurrentRobotId;
    probotmesg->header_data.receiver_ID       = GetReciverID(Receiver_Type);
    //按照协议赋值
    interactTxData[0]  = (uint8_t)JUDGE_FRAME_HEADER_SOF;
	
	Trans_Uint16ToChar(INTERNATION_DART_DATA_LENGTH, &interactTxData[1]);//飞镖单独拿出来写，后续可加switch
	interactTxData[3]  = InteractPackSeq++;
	if(InteractPackSeq >= 255) InteractPackSeq = 0;
	Append_CRC8_Check_Sum(interactTxData, JUDGE_FRAME_HEADER_LENGTH);
	Trans_Uint16ToChar(cmdID_ROBOT_INTER, &interactTxData[5]);
	Trans_Uint16ToChar(probotmesg->header_data.data_cmd_ID, &interactTxData[7]);
    Trans_Uint16ToChar(probotmesg->header_data.sender_ID, &interactTxData[9]);
    Trans_Uint16ToChar(probotmesg->header_data.receiver_ID, &interactTxData[11]);
/*	
	自定义数据端，可加switch判断发送数据内容，增添数据需改INTERNATION_DART_DATA_LENGTH
*/	
	Trans_Float2Char(1.55,&interactTxData[13]);

	Append_CRC16_Check_Sum(interactTxData, INTERNATION_DART_PACK_SIZE);
	if(__HAL_DMA_GET_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6) == RESET)
    {
        UARTxHandle.hdmatx->Instance->NDTR = (uint16_t)INTERNATION_DART_PACK_SIZE;
		SET_BIT(UARTxHandle.Instance->CR3, USART_CR3_DMAT);
        dma_send_handle.Instance->PAR = (uint32_t)&USARTx->DR;
        dma_send_handle.Instance->M0AR = (uint32_t)interactTxData;
        __HAL_DMA_ENABLE(UARTxHandle.hdmatx);
    }
    else
    {
        __HAL_DMA_CLEAR_FLAG(UARTxHandle.hdmatx, DMA_FLAG_TCIF2_6);
        __HAL_DMA_DISABLE(UARTxHandle.hdmatx);
    }
}


//uint8_t graphicTxData[GRAPHIC_DATA_PACK_SIZE];
//static void Graphic_TX_Message(P_graphic_interactive_mesg_t pgraphic_mesg);
//通过机器人当前ID得到对应客户端ID
static uint16_t GetClientID(uint16_t robot_id)
{
    switch (robot_id)
    {
        case (R_RobotId_Hero):      return R_ClientId_Hero;
        case (R_RobotId_Engineer):  return R_ClientId_Engineer;
        case (R_RobotId_Infantry1): return R_ClientId_Infantry1;
        case (R_RobotId_Infantry2): return R_ClientId_Infantry2;
        case (R_RobotId_Infantry3): return R_ClientId_Infantry3;
        case (R_RobotId_Aerial):    return R_ClientId_Aerial;
//        case (R_RobotId_Sentry):    return R_ClientId_Sentry;
        case (B_RobotId_Hero):      return B_ClientId_Hero;
        case (B_RobotId_Engineer):  return B_ClientId_Engineer;
        case (B_RobotId_Infantry1): return B_ClientId_Infantry1;
        case (B_RobotId_Infantry2): return B_ClientId_Infantry2;
        case (B_RobotId_Infantry3): return B_ClientId_Infantry3;
        case (B_RobotId_Aerial):    return B_ClientId_Aerial;
//        case (B_RobotId_Sentry):    return B_ClientId_Sentry;
        default:                 	return (uint16_t)0;
    }
}

static uint8_t GetTeamColor()
{
	if(CurrentRobotId < 0x10 && CurrentRobotId > 0)
		return Team_Red;//红方
	  return Team_Blue;//蓝方
}

static uint16_t GetReciverID(uint16_t robot_type)
{
	uint8_t team;
	team = GetTeamColor();
    switch (robot_type)
    {
        case (Robot_Dart): 
			if(team == Team_Red)	
				return R_RobotId_Dart;
			else 
				return B_RobotId_Dart;
        default:   return (uint16_t)0;
    }
}
//将串口发送的4字节数据转化为浮点型数
static float Trans_Char2Float(uint8_t *pData)
{
    typedef union
    {
        uint8_t charData[4];
        float  floatData;
    }_JUDGE_TransData, *P_JUDGE_TransData;

    _JUDGE_TransData    tmpDataBuff = {0};
    for(uint8_t i = 0;i < 4;i++)
    {
        tmpDataBuff.charData[i] = *(pData + i);
    }
    return (tmpDataBuff.floatData);
}
//将浮点数转化为4字符发送
static void Trans_Float2Char(float input, uint8_t *array)
{
    typedef union
    {
        uint8_t charData[4];
        float  floatData;
    }_JUDGE_TransData, *P_JUDGE_TransData;

    _JUDGE_TransData    tmpDataBuff = {0};
    tmpDataBuff.floatData = input;
    for(uint8_t i = 0;i < 4;i++)
    {
        *(array + i) = tmpDataBuff.charData[i];
    }
}
//将Unit16_t类型高低位取反
static void Trans_Uint16ToChar(uint16_t input, uint8_t *array)
{
    *(array)        = (uint8_t)(input & 0x00ff);
    *(array + 1)    = (uint8_t)((input >> 8) & 0x00ff);
}

//CRC 校验代码示例
//crc8 generator polynomial:G(x)=x8+x5+x4+1
const unsigned char CRC8_INIT = 0xff;
const unsigned char CRC8_TAB[256] =
{
    0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
    0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
    0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
    0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
    0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
    0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
    0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
    0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
    0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
    0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
    0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
    0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
    0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
    0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
    0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
    0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
};
unsigned char Get_CRC8_Check_Sum(unsigned char *pchMessage,unsigned int dwLength,unsigned char ucCRC8)
{
    unsigned char ucIndex;
    while (dwLength--)
    {
        ucIndex = ucCRC8^(*pchMessage++);
        ucCRC8 = CRC8_TAB[ucIndex];
    }
    return(ucCRC8);
}
/*
** Descriptions: CRC8 Verify function
** Input: Data to Verify,Stream length = Data + checksum
** Output: True or False (CRC Verify Result)
*/
static uint8_t Verify_CRC8_Check_Sum(unsigned char *pchMessage, unsigned int dwLength)
{
    unsigned char ucExpected = 0;
    if ((pchMessage == 0) || (dwLength <= 2)) return 0;
    ucExpected = Get_CRC8_Check_Sum (pchMessage, dwLength-1, CRC8_INIT);
    return ( ucExpected == pchMessage[dwLength-1] );
}
/*
** Descriptions: append CRC8 to the end of data
** Input: Data to CRC and append,Stream length = Data + checksum
** Output: True or False (CRC Verify Result)
*/
static void Append_CRC8_Check_Sum(unsigned char *pchMessage, unsigned int dwLength)
{
    unsigned char ucCRC = 0;
    if ((pchMessage == 0) || (dwLength <= 2)) return;
    ucCRC = Get_CRC8_Check_Sum ( (unsigned char *)pchMessage, dwLength-1, CRC8_INIT);
    pchMessage[dwLength-1] = ucCRC;
}
uint16_t CRC_INIT = 0xffff;
const uint16_t wCRC_Table[256] =
{
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
/*
** Descriptions: CRC16 checksum function
** Input: Data to check,Stream length, initialized checksum
** Output: CRC checksum
*/
uint16_t Get_CRC16_Check_Sum(uint8_t *pchMessage,uint32_t dwLength,uint16_t wCRC)
{
    uint8_t chData;
    if (pchMessage == NULL)
    {
        return 0xFFFF;
    }
    while(dwLength--)
    {
        chData = *pchMessage++;
        (wCRC) = ((uint16_t)(wCRC) >> 8) ^ wCRC_Table[((uint16_t)(wCRC) ^ (uint16_t)(chData)) & 0x00ff];
    }
    return wCRC;
}
/*
** Descriptions: CRC16 Verify function
** Input: Data to Verify,Stream length = Data + checksum
** Output: True or False (CRC Verify Result)
*/
static uint32_t Verify_CRC16_Check_Sum(uint8_t *pchMessage, uint32_t dwLength)
{
    uint16_t wExpected = 0;
    if ((pchMessage == NULL) || (dwLength <= 2))
    {
        return 0;
    }
    wExpected = Get_CRC16_Check_Sum ( pchMessage, dwLength - 2, CRC_INIT);
    return ((wExpected & 0xff) == pchMessage[dwLength - 2] && ((wExpected >> 8) & 0xff) == pchMessage[dwLength - 1]);
}
/*
** Descriptions: append CRC16 to the end of data
** Input: Data to CRC and append,Stream length = Data + checksum
** Output: True or False (CRC Verify Result)
*/
static void Append_CRC16_Check_Sum(uint8_t * pchMessage,uint32_t dwLength)
{
    uint16_t wCRC = 0;
    if ((pchMessage == NULL) || (dwLength <= 2))
    {
        return;
    }
    wCRC = Get_CRC16_Check_Sum ( (uint8_t *)pchMessage, dwLength-2, CRC_INIT );
    pchMessage[dwLength-2] = (uint8_t)(wCRC & 0x00ff);
    pchMessage[dwLength-1] = (uint8_t)((wCRC >> 8)& 0x00ff);
}

